package com.example.tsbs.util;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.FloatByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LightSoUtil {

    /**
     * so库映射的接口
     */
    private interface SoLib extends Library {

        /**
         * 映射的方法 LIGHT_target_free_light
         * @return
         */
        int LIGHT_target_free_light(String TargetFileName, String[] BoundaryFileName,
                                    float SourceX0, float SourceY0, float SourceZ0,
                                    float SourceRX0, float SourceRY0, float SourceRZ0,
                                    float frec_low, float frec_step, float frec_high,
                                    float LaunchCenterFrec, float LaunchPulseWidth,
                                    float ReceiveSigWidth, float FrecSample,
                                    IntByReference count_lights, PointerByReference XData,
                                    PointerByReference YData, PointerByReference ZData, PointerByReference WData);
    }

    /**
     * 加载so库
     */
    private static class SoLibImpl implements SoLib {

        static SoLib INSTANCE;

        static {
            try {
                // 也可以采用其他方法加载so库文件,或将so文件放在项目中
//                INSTANCE = (SoLib) Native.synchronizedLibrary((SoLib) Native.loadLibrary("/usr/local/lib.so", SoLib.class));
                SoLib INSTANTCE = Native.load("/root/danjidi/light/libLIGHT_TARGET.so", SoLib.class);
                log.info("so库[/root/danjidi/light/libLIGHT_TARGET.so]加载成功!");
            } catch (Exception e) {
                // 异常处理
                INSTANCE = null;
                log.info("so库[/root/danjidi/light/libLIGHT_TARGET.so]加载失败!");
            }
        }

        @Override
        public native int LIGHT_target_free_light(String TargetFileName, String[] BoundaryFileName,
                                                  float SourceX0, float SourceY0, float SourceZ0,
                                                  float SourceRX0, float SourceRY0, float SourceRZ0,
                                                  float frec_low, float frec_step, float frec_high,
                                                  float LaunchCenterFrec, float LaunchPulseWidth,
                                                  float ReceiveSigWidth, float FrecSample,
                                                  IntByReference count_lights, PointerByReference XData,
                                                  PointerByReference YData, PointerByReference ZData, PointerByReference WData);
    }

    /**
     * 对外暴露的工具方法,在此方法中调用so库中的native方法
     * @return
     */
    public static int lightSo() {
            String ddtPath = "/root/danjidi/light/bechmark_double_all.DDT";
            String[] files = new String[]{"/root/danjidi/light/water_steel(8mm)_water_V.dat",
                    "/root/danjidi/light/water_steel(4mm)_air_V.dat",
                    "/root/danjidi/light/water_steel(8mm)_water_T.dat",
                    "/root/danjidi/light/water_AL(10mm)_air_T.dat"};
            float LaunchCenterFrec = 5000f;
            float LaunchPulseWidth = 0.001f;
            float ReceiveSigWidth = 0.2f;
            float FrecSample = 6 * LaunchCenterFrec;
            IntByReference count_lights = new IntByReference();
            FloatByReference floatByReference1 = new FloatByReference();
            Pointer pfloat1 = floatByReference1.getPointer();
            FloatByReference floatByReference2 = new FloatByReference();
            Pointer pfloat2 = floatByReference2.getPointer();
            FloatByReference floatByReference3 = new FloatByReference();
            Pointer pfloat3 = floatByReference3.getPointer();
            FloatByReference floatByReference4 = new FloatByReference();
            Pointer pfloat4 = floatByReference4.getPointer();
            PointerByReference  XData = new PointerByReference(pfloat1);
            PointerByReference  YData = new PointerByReference(pfloat2);
            PointerByReference  ZData = new PointerByReference(pfloat3);
            PointerByReference  WData = new PointerByReference(pfloat4);

        if (null != SoLibImpl.INSTANCE) {
            int test = SoLibImpl.INSTANCE.LIGHT_target_free_light(ddtPath,files, 0,0,5000,
                    0,0,5000,100,10,10000,
                    LaunchCenterFrec,LaunchPulseWidth,ReceiveSigWidth,FrecSample,
                    count_lights,XData,YData,ZData,WData);
            System.out.println(XData.getValue());
            return test;
        } else {
            throw new RuntimeException("无法执行native方法,请检查so库文件是否存在或接口是否存在!");
        }
    }

}
